// ****************************************************************
// Copyright 2012, Stephan Burguchev
// e-mail: me@sburg.net
// ****************************************************************
// *
using System;
using System.IO;
using System.Reflection;

namespace Updater.Utils
{
    public class AssemblyAttributesReader
    {
        private readonly Assembly _assembly;

        public AssemblyAttributesReader(Assembly assembly)
        {
            this._assembly = assembly;
        }

        public AssemblyAttributesReader()
        {
        }

        public string AssemblyCompany
        {
            get
            {
                var title = this.getAssemblyAttribute<AssemblyCompanyAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Company))
                {
                    return "";
                }
                return title.Company;
            }
        }

        public string AssemblyConfiguration
        {
            get
            {
                var title = this.getAssemblyAttribute<AssemblyConfigurationAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Configuration))
                {
                    return "";
                }
                return title.Configuration;
            }
        }

        public string AssemblyCopyright
        {
            get
            {
                var title = this.getAssemblyAttribute<AssemblyCopyrightAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Copyright))
                {
                    return "";
                }
                return title.Copyright;
            }
        }

        public string AssemblyDescription
        {
            get
            {
                var title = this.getAssemblyAttribute<AssemblyDescriptionAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Description))
                {
                    return "";
                }
                return title.Description;
            }
        }

        public string AssemblyProduct
        {
            get
            {
                var title = this.getAssemblyAttribute<AssemblyProductAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Product))
                {
                    return "";
                }
                return title.Product;
            }
        }

        /// <summary>
        ///     Gets the assembly title.
        /// </summary>
        /// <value>The assembly title.</value>
        public string AssemblyTitle
        {
            get
            {
                string defaultTitle = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
                var title = this.getAssemblyAttribute<AssemblyTitleAttribute>();
                if (title == null || string.IsNullOrEmpty(title.Title))
                {
                    // If there was no Title attribute, or if the Title attribute was the empty string, return the .exe name
                    return defaultTitle;
                }
                // If it is not an empty string, return it
                return title.Title;
            }
        }

        public string AssemblyVersion
        {
            get
            {
                var attr = this.getAssemblyAttribute<AssemblyVersionAttribute>();
                if (attr == null || string.IsNullOrEmpty(attr.Version))
                {
                    var attr2 = this.getAssemblyAttribute<AssemblyFileVersionAttribute>();
                    if (attr2 == null || string.IsNullOrEmpty(attr2.Version))
                    {
                        return "";
                    }
                    return attr2.Version;
                }
                return attr.Version;
            }
        }

        private TAttr getAssemblyAttribute<TAttr>() where TAttr : Attribute
        {
            // Get all Title attributes on this assembly
            Assembly assembly = this._assembly ?? Assembly.GetExecutingAssembly();
            object[] attributes = assembly.GetCustomAttributes(typeof(TAttr), false);

            // If there is at least one attribute
            if (attributes.Length > 0)
            {
                // Select the first one
                var attribute = (TAttr)attributes[0];
                return attribute;
            }

            return null;
        }
    }
}
